<?php
/**
 * 签名调试脚本
 * 用于验证客户端和服务端签名生成是否一致
 */

// API配置
$apiKey = 'ak_3d97ebf664db97f3023b336f5fc0ad23';
$secretKey = 'e61b4d35cf2a29e46e08e36dd075ea585614cd91470719c4411d2b946f677e12';

// 测试数据
$method = 'POST';
$path = 'api/device/command';
$timestamp = time();
$data = [
    'imei' => '863780074784151',
    'type' => 'reboot'
];
$body = json_encode($data, JSON_UNESCAPED_UNICODE);

echo "=== 签名调试信息 ===\n";
echo "API Key: {$apiKey}\n";
echo "Secret Key: {$secretKey}\n";
echo "Method: {$method}\n";
echo "Path: {$path}\n";
echo "Timestamp: {$timestamp}\n";
echo "Body: {$body}\n";
echo "\n";

// 构建待签名字符串
$stringToSign = strtoupper($method) . "\n" . $path . "\n" . $timestamp . "\n" . $body;

echo "=== 待签名字符串 ===\n";
echo "格式: METHOD\\nPATH\\nTIMESTAMP\\nBODY\n";
echo "内容:\n";
echo "---开始---\n";
echo $stringToSign;
echo "\n---结束---\n\n";

// 显示每个部分
$parts = explode("\n", $stringToSign);
echo "=== 签名字符串各部分 ===\n";
echo "第1部分 (METHOD): '{$parts[0]}'\n";
echo "第2部分 (PATH): '{$parts[1]}'\n";
echo "第3部分 (TIMESTAMP): '{$parts[2]}'\n";
echo "第4部分 (BODY): '{$parts[3]}'\n";
echo "\n";

// 生成签名
$signature = hash_hmac('sha256', $stringToSign, $secretKey);

echo "=== 签名结果 ===\n";
echo "HMAC-SHA256签名: {$signature}\n";
echo "\n";

// 构建请求头
$headers = [
    'Authorization: ApiKey ' . $apiKey,
    'Timestamp: ' . $timestamp,
    'Signature: ' . $signature,
    'Content-Type: application/json'
];

echo "=== 请求头 ===\n";
foreach ($headers as $header) {
    echo "{$header}\n";
}
echo "\n";

// 发送测试请求
echo "=== 发送测试请求 ===\n";
$url = 'http://localhost:8000/api/device/command';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);

echo "HTTP状态码: {$httpCode}\n";
if ($error) {
    echo "cURL错误: {$error}\n";
}

echo "响应内容:\n";
if ($response) {
    $jsonData = json_decode($response, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        echo json_encode($jsonData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
    } else {
        echo $response . "\n";
    }
} else {
    echo "无响应内容\n";
}

echo "\n=== 验证步骤 ===\n";
echo "1. 检查时间戳是否在有效范围内（5分钟内）\n";
echo "2. 检查签名字符串格式是否正确\n";
echo "3. 检查HMAC-SHA256计算是否正确\n";
echo "4. 检查请求头格式是否正确\n";

// 验证时间戳
$currentTime = time();
$timeDiff = abs($currentTime - $timestamp);
echo "\n=== 时间戳验证 ===\n";
echo "当前时间: {$currentTime}\n";
echo "请求时间: {$timestamp}\n";
echo "时间差: {$timeDiff}秒\n";
echo "是否有效: " . ($timeDiff <= 300 ? "是" : "否") . "\n";

// 生成一个新的时间戳进行对比测试
echo "\n=== 使用新时间戳重新测试 ===\n";
$newTimestamp = time();
$newStringToSign = strtoupper($method) . "\n" . $path . "\n" . $newTimestamp . "\n" . $body;
$newSignature = hash_hmac('sha256', $newStringToSign, $secretKey);

echo "新时间戳: {$newTimestamp}\n";
echo "新签名: {$newSignature}\n";

// 用新签名发送请求
$newHeaders = [
    'Authorization: ApiKey ' . $apiKey,
    'Timestamp: ' . $newTimestamp,
    'Signature: ' . $newSignature,
    'Content-Type: application/json'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, $newHeaders);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$newResponse = curl_exec($ch);
$newHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "新请求HTTP状态码: {$newHttpCode}\n";
echo "新请求响应:\n";
if ($newResponse) {
    $newJsonData = json_decode($newResponse, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        echo json_encode($newJsonData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
    } else {
        echo $newResponse . "\n";
    }
}
?>
